/*
  by Marcos Assis, 2011, (slightly) based on C version created by Robin Hewitt, 2007
  see copyright license "License Original camshift_wrapper.txt" for the original work
  this version is under GNU GPL v3
*/

#ifndef CAMSHIFT_WRAPPER_H
#define CAMSHIFT_WRAPPER_H

#include "cv.h"
#include "chronometer.h"

class camshift_wrapper
{
protected:
  // Parameters
  int   nHistBins;                 // number of histogram bins
  float rangesArr[2];          // histogram range
  int vmin; // limits for calculating hue
  int vmax;
  int smin;                       

  //IplImage * pHSVImg ; // the input image converted to HSV color mode
  //IplImage * pHueImg ; // the Hue channel of the HSV image
  //IplImage * pMask   ; // this image is used for masking pixels
  //IplImage * pProbImg; // the face probability estimates for each pixel
  //CvHistogram * pHist; // histogram of hue in the original face image

  cv::Mat hsvImg;
  cv::Mat hueImg;
  cv::Mat mask;
  cv::Mat probImg;
  cv::Mat hist;
  
  //CvRect prevFaceRect;  // location of face in previous frame
  //CvBox2D faceBox;      // current face-location estimate

  cv::Rect trackWindow;
  cv::TermCriteria criteria;
  cv::RotatedRect trackBox;

  int nFrames;
  bool started_;
  bool lost_;
  chronometer chr;

  void update_hue_image(const cv::Mat& img);

public:
  camshift_wrapper(int vmin=65, int vmax=256, int smin=55, int nHistBins=30)
    :nHistBins(nHistBins), vmin(vmin), vmax(vmax), smin(smin),
    criteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER, 10, 1), nFrames(0), started_(false), lost_(true), chr(0)
  {
    rangesArr[0] = 0;
    rangesArr[1] = 180;
  }
  camshift_wrapper(int vmin, int vmax, int smin, int nHistBins, float rangesArr[])
    :nHistBins(nHistBins), vmin(vmin), vmax(vmax), smin(smin),
    criteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER, 10, 1), nFrames(0), started_(false), lost_(true), chr(0)
  {
    rangesArr[0] = rangesArr[0];
    rangesArr[1] = rangesArr[1];
  }
  ~camshift_wrapper()
  {
    release_tracker();
  }

  // Main Control functions
  void    release_tracker();
  void    start_tracking(const cv::Mat& img, const cv::Rect& rect);
  cv::RotatedRect track(const cv::Mat& img);


  // Parameter settings
  void set_vmin(int vmin)
  {
    this->vmin = vmin;
  }
  void set_smin(int smin)
  {
    this->smin = smin;
  }
  void set_vmax(int vmax)
  {
    this->vmax = vmax;
  }

  int get_vmin() const
  {
    return vmin;
  }
  int get_smin() const
  {
    return smin;
  }
  int get_vmax() const
  {
    return vmax;
  }

  bool started() const
  {
    return started_;
  }
  bool lost() const
  {
    return lost_;
  }

  const cv::Mat& probability_image() const
  {
    return probImg;
  }

  cv::Mat hist_image() const;

  chronometer get_chronometer() const
  {
    return chr;
  }
};

#endif

